package com.sec.etech.process.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sec.etech.bpm.cust.service.EtechBpmService;
import com.sec.etech.common.service.CommonService;
import com.sec.etech.file.service.EtechWebUploaderService;
import com.sec.etech.org.service.EtechUserUtil;
import com.sec.etech.process.mapper.PartsTechAmendMapper;
import com.sec.etech.process.mapper.PartsTechMapper;
import com.sec.etech.process.mapper.SppRouteRevMapper;
import com.sec.etech.process.model.*;
import com.sec.etech.sys.util.ContextUtil;
import org.openbpm.base.api.exception.BusinessException;
import org.openbpm.base.core.id.IdUtil;
import org.openbpm.base.core.util.StringUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class SppRouteRevService extends ServiceImpl<SppRouteRevMapper, SppRouteRev> {

    @Resource
    private JdbcTemplate jdbcTemplate;
    @Resource
    private SppRelFileService sppRelFileService;
    @Resource
    private SppRelSamService sppRelSamService;
    @Resource
    private SppRelToolService sppRelToolService;
    @Resource
    private SppRouteOpService sppRouteOpService;
    @Resource
    private SppRouteStepService sppRouteStepService;
    @Resource
    private EtechWebUploaderService etechWebUploaderService;
    @Resource
    private CommonService commonService;
    @Resource
    private PartsTechMapper partsTechMapper;
    @Resource
    private PartsTechAmendMapper partsTechAmendMapper;
    @Resource
    private EtechBpmService etechBpmService;


    private static final int REL_TARGET_TYPE = 1;

    //获取工序卡下一个流水号
    private synchronized String getNextRouteCardSerial(){
        String sql = "select max(serial_num) maxSerial from spp_route_rev where is_template=0 and serial_num like 'GY%' and serial_num not like 'GYM%'";
        String maxSerial = jdbcTemplate.queryForObject(sql, String.class);
        return "GY" + String.format("%08d", Integer.parseInt(maxSerial.substring(2)) + 1);
    }

    //更新当前版本标志
    public void updateCurrVersion(Long processId) {
        baseMapper.update(null, Wrappers.<SppRouteRev>lambdaUpdate()
                .eq(SppRouteRev::getProcessid, processId).eq(SppRouteRev::getActive, 1)
                .set(SppRouteRev::getCurrVer, 1).set(SppRouteRev::getStatusid, 3));
    }
    //更新新版路线卡的状态和版本等
    public void updateCurrVersionAmend(Long amendId){
        String sql = "select t1.parts_amend_id,t1.target_id,t1.new_target_id,t1.change_mode,t2.version " +
                "from proc_parts_tech_amend t1 left join spp_route_rev t2 on t1.target_id=t2.route_rev_id " +
                "where t1.target_type=1 and t1.amendid=?";
        List<Map<String,Object>> amendList = jdbcTemplate.queryForList(sql, amendId);
        for(Map<String,Object> map:amendList) {
            if(map.get("target_id")!=null && (Long)map.get("target_id")>0) {
                SppRouteRev oldRouteRev = new SppRouteRev();
                oldRouteRev.setRouteRevId((Long) map.get("target_id"));
                oldRouteRev.setCurrVer(0);
                super.updateById(oldRouteRev);
            }
            String version = map.get("version")!=null ? String.format("%02d", Integer.parseInt(map.get("version").toString()) + 1) : "00";
            SppRouteRev newRouteRev = new SppRouteRev();
            newRouteRev.setRouteRevId((Long) map.get("new_target_id"));
            newRouteRev.setCurrVer(1);
            newRouteRev.setStatusid(3);
            newRouteRev.setVersion(version);
            if((Integer)map.get("change_mode")==0) {//删除
                newRouteRev.setActive(0);
            }
            super.updateById(newRouteRev);
        }
    }
    public String checkProcessStatusFinishAmend(Long processId, Long amendId) {
        String sql = "select p.typeid,p.plantaskid,pt.cardtype from proc_process p, proc_process_z_type pt where p.typeid=pt.typeid and p.processid=?";
        List<Map<String,Object>> typeList = jdbcTemplate.queryForList(sql, processId);
        Integer cardType = (Integer) typeList.get(0).get("cardtype");
        if(cardType==1) {
            sql = "SELECT t1.parts_amend_id FROM proc_parts_tech_amend t1, spp_route_rev t2 " +
                    "where t1.new_target_id=t2.route_rev_id and (t2.statusid not in (2,3) or t2.statusid is null) and t1.amendid=?";
        }else if(cardType==2) {
            sql = "SELECT t1.parts_amend_id FROM proc_parts_tech_amend t1, spp_operation_rev t2 " +
                    "where t1.new_target_id=t2.op_rev_id and (t2.statusid not in (2,3) or t2.statusid is null) and t1.amendid=?";
        }
        List<Map<String,Object>> amendList = jdbcTemplate.queryForList(sql, amendId);
        if(amendList!=null && amendList.size()>0) {
            return "修改清单下所有结构工艺卡的状态为“已完成”才可提交！";
        }
        return "";
    }
    //检查工序卡状态
    /*public String checkProcessStatusFinish(Long processId) {
        String sql = "select p.typeid,p.plantaskid,pt.cardtype,pt.direct from proc_process p, proc_process_z_type pt where p.typeid=pt.typeid and p.processid=?";
        List<Map<String,Object>> typeList = jdbcTemplate.queryForList(sql, processId);
        Integer cardType = (Integer) typeList.get(0).get("cardtype");
        String direct = typeList.get(0).get("direct").toString();
        Long typeId = (Long) typeList.get(0).get("typeid");
        if(cardType==1) {
            return this.checkProcessStatusFinish(processId, typeId);
        }else if(cardType==2) {
            return sppOperationRevService.checkProcessStatusFinish(processId, (Long) typeList.get(0).get("plantaskid"), direct);
        }
        return "";
    }*/
    //检查所有结构工艺卡的状态是否为“已完成”
    public String checkProcessStatusFinish(Long processId, Long typeId) {
        String sql = "select count(1) num from spp_route_rev where (processid=? or processid in (select processid from proc_process where parentid=? and active=1)) and curr_ver=1 " +
                "and (statusid not in (2,3) or statusid is null) and process_type_id=(select process_type_id from spp_route_z_process_type where code=(select direct from proc_process_z_type where typeid=?))";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, processId, processId, typeId);

        if (list != null && list.size() > 0 && Integer.parseInt(list.get(0).get("num").toString()) > 0) {
            return "部套下所有结构工艺卡的状态为“已完成”才可提交！";
        } else {
            return "";
        }
    }

    //更新路线卡状态为已完成/编制中
    public void updateRouteStatus(Long routeRevId, Integer statusId) {
        SppRouteRev rev = new SppRouteRev();
        rev.setRouteRevId(routeRevId);
        rev.setStatusid(statusId==1 ? 2 : 1);
        rev.setDesignerUid(Long.parseLong(ContextUtil.getCurrentUserId()));
        super.updateById(rev);
    }

    public String saveOrUpdateForLine(JSONObject object) throws Exception {
        //检查工序号是否重复
        String msg = sppRouteOpService.checkOpNo(object);
        if (!"success".equals(msg)) {
            return msg;
        }
        //检查工步号是否重复
        msg = sppRouteStepService.checkStepNo(object);
        if (!"success".equals(msg)) {
            return msg;
        }
        Long routeRevId = object.getLong("route_rev_id");
        String module = object.getString("module");
        //String amends = object.getString("amends");
        List<JSONObject> objectList = (List<JSONObject>) object.get("dataList");
        for (JSONObject obj : objectList) {//删除或者更新
            sppRouteOpService.saveOrUpdateByObject(obj, routeRevId, module);
        }
        return "success";
    }


    //新旧零件评级数据比较同步路线卡数据
    public void creatOrDeleteRouteRevs(PartsTech oldPartsTech, PartsTech partsTech, Map<String, Long> processMap, JSONObject object) {
        //判断新增的情况
        if ((oldPartsTech.getHasMetal() == null || oldPartsTech.getHasMetal() == 0)
                && partsTech.getHasMetal() != null && partsTech.getHasMetal() == 1) {//金工
            object.put("processid", processMap.get("12"));
            this.creatRouteRev(object, "metal");
        }
        if ((oldPartsTech.getHasAssembleWeld() == null || oldPartsTech.getHasAssembleWeld() == 0)
                && partsTech.getHasAssembleWeld() != null && partsTech.getHasAssembleWeld() == 1) {//装焊
            object.put("processid", processMap.get("15"));
            this.creatRouteRev(object, "assembleWeld");
        }
        if ((oldPartsTech.getHasCold() == null || oldPartsTech.getHasCold() == 0)
                && partsTech.getHasCold() != null && partsTech.getHasCold() == 1) {//冷作
            object.put("processid", processMap.get("14"));
            this.creatRouteRev(object, "cold");
        }
        if ((oldPartsTech.getHasHot() == null || oldPartsTech.getHasHot() == 0)
                && partsTech.getHasHot() != null && partsTech.getHasHot() == 1) {//热锻
            object.put("processid", processMap.get("16"));
            this.creatRouteRev(object, "hot");
        }
        if ((oldPartsTech.getHasMetalRotate() == null || oldPartsTech.getHasMetalRotate() == 0)
                && partsTech.getHasMetalRotate() != null && partsTech.getHasMetalRotate() == 1) {//五金
            object.put("processid", processMap.get("31"));
            this.creatRouteRev(object, "metalRotate");
        }
        //判断删除的情况
        if ((partsTech.getHasMetal() == null || partsTech.getHasMetal() == 0)
                && oldPartsTech.getHasMetal() != null && oldPartsTech.getHasMetal() == 1) {//金工
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "metal");
        }
        if ((partsTech.getHasAssembleWeld() == null || partsTech.getHasAssembleWeld() == 0)
                && oldPartsTech.getHasAssembleWeld() != null && oldPartsTech.getHasAssembleWeld() == 1) {//装焊
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "assembleWeld");
        }
        if ((partsTech.getHasCold() == null || partsTech.getHasCold() == 0)
                && oldPartsTech.getHasCold() != null && oldPartsTech.getHasCold() == 1) {//冷作
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "cold");
        }
        if ((partsTech.getHasHot() == null || partsTech.getHasHot() == 0)
                && oldPartsTech.getHasHot() != null && oldPartsTech.getHasHot() == 1) {//热锻
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "hot");
        }
        if ((partsTech.getHasMetalRotate() == null || partsTech.getHasMetalRotate() == 0)
                && oldPartsTech.getHasMetalRotate() != null && oldPartsTech.getHasMetalRotate() == 1) {//五金
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "metalRotate");
        }
    }
    //生成路线卡
    public List<Long> createRouteRevs(Long planTaskId, String planTaskName, String materialNo, Map<String, Long> processIdMap) {
        List<Long> routeRevIdList = new ArrayList<>();
        String sql = "select p.partsid,p.partsnum,p.partsname,p.parts_SAPnum,pt.has_metal,pt.has_cold,pt.has_assemble_weld,pt.has_hot,pt.has_metal_rotate " +
                "from proc_parts_tech pt, prod_parts p where pt.partsid=p.partsid and pt.componentid=?";
        List<Map<String,Object>> partsTechList = jdbcTemplate.queryForList(sql, planTaskId);
        if(partsTechList!=null && partsTechList.size()>0) {
            for(Map<String,Object> map:partsTechList) {
                JSONObject object = new JSONObject(map);
                object.put("plantaskid", planTaskId);
                if (object.get("has_metal") != null && object.getInteger("has_metal") == 1) {//金工
                    object.put("processid", processIdMap.get("metal"));
                    Long routeRevId = this.creatRouteRev(object, "metal");
                    routeRevIdList.add(routeRevId);
                }
                if (object.get("has_assemble_weld") != null && object.getInteger("has_assemble_weld") == 1) {//装焊
                    object.put("processid", processIdMap.get("assembleWeld"));
                    Long routeRevId = this.creatRouteRev(object, "assembleWeld");
                    routeRevIdList.add(routeRevId);
                }
                if (object.get("has_cold") != null && object.getInteger("has_cold") == 1) {//冷作
                    object.put("processid", processIdMap.get("cold"));
                    Long routeRevId = this.creatRouteRev(object, "cold");
                    routeRevIdList.add(routeRevId);
                }
                if (object.get("has_hot") != null && object.getInteger("has_hot") == 1) {//热锻
                    object.put("processid", processIdMap.get("hot"));
                    Long routeRevId = this.creatRouteRev(object, "hot");
                    routeRevIdList.add(routeRevId);
                }
                if (object.get("has_metal_rotate") != null && object.getInteger("has_metal_rotate") == 1) {//五金
                    object.put("processid", processIdMap.get("metalRotate"));
                    Long routeRevId = this.creatRouteRev(object, "metalRotate");
                    routeRevIdList.add(routeRevId);
                }
            }
        }
        if(processIdMap.containsKey("assembleFit")){
            JSONObject object = new JSONObject();
            object.put("processid", processIdMap.get("assembleFit"));
            object.put("plantaskid", planTaskId);
            object.put("plantaskname", planTaskName);
            object.put("materialNo", materialNo);
            Long routeRevId = this.creatRouteRev(object, "assembleFit");
            routeRevIdList.add(routeRevId);
        }
        return routeRevIdList;
    }
    //新旧零件评级数据比较同步路线卡数据
    /*public void creatOrDeleteRouteRevs(PartsTech oldPartsTech, PartsTech partsTech, JSONObject techObj, Map<String, Long> processMap, JSONObject object) {
        //判断新增的情况
        if ((oldPartsTech.getHasMetal() == null || oldPartsTech.getHasMetal() == 0)
                && partsTech.getHasMetal() != null && partsTech.getHasMetal() == 1) {//金工
            object.put("processid", processMap.get("12"));
            this.creatRouteRev(techObj, object, "metal");
        }
        if ((oldPartsTech.getHasAssembleWeld() == null || oldPartsTech.getHasAssembleWeld() == 0)
                && partsTech.getHasAssembleWeld() != null && partsTech.getHasAssembleWeld() == 1) {//装焊
            object.put("processid", processMap.get("15"));
            this.creatRouteRev(techObj, object, "assembleWeld");
        }
        if ((oldPartsTech.getHasCold() == null || oldPartsTech.getHasCold() == 0)
                && partsTech.getHasCold() != null && partsTech.getHasCold() == 1) {//冷作
            object.put("processid", processMap.get("14"));
            this.creatRouteRev(techObj, object, "cold");
        }
        if ((oldPartsTech.getHasHot() == null || oldPartsTech.getHasHot() == 0)
                && partsTech.getHasHot() != null && partsTech.getHasHot() == 1) {//热锻
            object.put("processid", processMap.get("16"));
            this.creatRouteRev(techObj, object, "hot");
        }
        if ((oldPartsTech.getHasMetalRotate() == null || oldPartsTech.getHasMetalRotate() == 0)
                && partsTech.getHasMetalRotate() != null && partsTech.getHasMetalRotate() == 1) {//五金
            object.put("processid", processMap.get("31"));
            this.creatRouteRev(techObj, object, "metalRotate");
        }
        //判断删除的情况
        if ((partsTech.getHasMetal() == null || partsTech.getHasMetal() == 0)
                && oldPartsTech.getHasMetal() != null && oldPartsTech.getHasMetal() == 1) {//金工
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "metal");
        }
        if ((partsTech.getHasAssembleWeld() == null || partsTech.getHasAssembleWeld() == 0)
                && oldPartsTech.getHasAssembleWeld() != null && oldPartsTech.getHasAssembleWeld() == 1) {//装焊
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "assembleWeld");
        }
        if ((partsTech.getHasCold() == null || partsTech.getHasCold() == 0)
                && oldPartsTech.getHasCold() != null && oldPartsTech.getHasCold() == 1) {//冷作
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "cold");
        }
        if ((partsTech.getHasHot() == null || partsTech.getHasHot() == 0)
                && oldPartsTech.getHasHot() != null && oldPartsTech.getHasHot() == 1) {//热锻
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "hot");
        }
        if ((partsTech.getHasMetalRotate() == null || partsTech.getHasMetalRotate() == 0)
                && oldPartsTech.getHasMetalRotate() != null && oldPartsTech.getHasMetalRotate() == 1) {//五金
            this.deleteRouteRev(oldPartsTech.getComponentid(), partsTech.getPartsid(), "metalRotate");
        }
    }*/

    public void delOpOrStep(Long routeStepId, String amends) {
        SppRouteStep step = sppRouteStepService.getById(routeStepId);
        // TODO 删除工序/工步后重新排序
        // 假定用户不会只删01工步
        if ("01".equals(step.getStepNo())) {//删除工序和所属工步
            sppRouteOpService.delOperation(step, amends);
        } else {//删除工步
            sppRouteStepService.delStep(step, amends);
            //sppRouteStepService.removeById(routeStepId);
        }
    }

    /**
     * 添加附件
     *
     * @param paramMap
     * @return
     * @throws Exception
     */
    public String addAttachments(Map<String, Object> paramMap) throws Exception {
        Long routeRevId = MapUtil.getLong(paramMap, "targetId");
        JSONArray jsonArray = cn.hutool.json.JSONUtil.parseArray(MapUtil.getStr(paramMap, "fileList"));
        if (CollUtil.isNotEmpty(jsonArray)) {
            List<String> fileids = CollUtil.newArrayList();
            for (Object o : jsonArray) {
                cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(o);
                fileids.add(jsonObject.getStr("id"));
                sppRelFileService.saveRelFile(REL_TARGET_TYPE, routeRevId, jsonObject.getStr("id"), jsonObject.getStr("name"));
            }
            etechWebUploaderService.batchMoveTempFileToFormalFile(fileids);
        }
        return "success";
    }

    //删除附件
    public void delAttachment(Long relFileId) {
        sppRelFileService.delAttachment(relFileId);
    }

    /**
     * 获取附件
     *
     * @param routeRevId
     * @param onlyPdf    只查pdf
     * @return
     */
    public List<Map<String, Object>> getAttachments(Long routeRevId, boolean onlyPdf) {
        return sppRelFileService.getAttachments(routeRevId, REL_TARGET_TYPE, onlyPdf);
    }

    /**
     * 重排序附件
     *
     * @param paramMap
     */
    public void reorderAttachments(Map<String, Object> paramMap) {
        Long routeRevId = MapUtil.getLong(paramMap, "targetId");
        JSONArray jsonArray = cn.hutool.json.JSONUtil.parseArray(MapUtil.getStr(paramMap, "relFileIds"));
        if (CollUtil.isNotEmpty(jsonArray)) {
            List<String> relFileIds = CollUtil.newArrayList();
            for (Object o : jsonArray) {
                relFileIds.add(o.toString());
            }
            sppRelFileService.reorder(routeRevId, REL_TARGET_TYPE, relFileIds);
        }
    }

    //获取上汽、非上汽标准
    public List getSams(String keyWords) {
        String sql = "select * from (select t0.pk_id,t0.code AS sam_code,t0.name AS sam_name,t0.status_id," +
                "(case t0.status_id when 1 then '正 常' when 2 then '编制中' when 3 then '暂 缓' when 4 then '修订中' " +
                "when 5 then '已废止' when 6 then '被替代' else '' end) AS status_name, 'secs' type from sam_secs t0 " +
                "left join sam_secs_z_status t1 on t0.status_id = t1.pk_id where t0.pk_id > 0 and t0.active = 1 and t0.name like ? " +
                "union all " +
                "select t0.pk_id,t0.primary_code AS sam_code,t0.primary_name AS sam_name,t0.status_id," +
                "(case t0.status_id when 1 then '正 常' when 2 then '被替代' when 3 then '已作废' when 4 then '正常(S分包专用)' end) " +
                "AS status_name, 'notsecs' type from sam_notsecs t0 left join sam_notsecs_z_status t1 on t0.status_id = t1.pk_id " +
                "where t0.pk_id > 0 and t0.active = 1 and t0.primary_name like ?) t limit 10";
        List<Map<String, Object>> samList = jdbcTemplate.queryForList(sql, "%" + keyWords + "%", "%" + keyWords + "%");
        return samList;
    }

    /**
     * 获取已关联技术规范
     *
     * @param routeRevId
     * @return
     */
    public List<Map<String, Object>> getRefSams(Long routeRevId, Long stepId) {
        return sppRelSamService.getRefSams(routeRevId, REL_TARGET_TYPE, stepId);
    }

    /**
     * 更新关联技术规范
     *
     * @param paramMap
     */
    public void updateRefSam(Map<String, Object> paramMap) {
        Long routeRevId = MapUtil.getLong(paramMap, "targetId");
        Long stepId = MapUtil.getLong(paramMap, "stepId");
        JSONArray jsonArray = cn.hutool.json.JSONUtil.parseArray(MapUtil.getStr(paramMap, "samList"));
        sppRelSamService.updateRefSam(routeRevId, REL_TARGET_TYPE, stepId, jsonArray);
    }

    //路线卡评级分解权限校验
    public Map<String, Integer> checkRateDecoPower(Long componentId) throws Exception {
        Map<String, Integer> map = new HashMap<>();
        String sql = "SELECT t.metalLevel,t.coldLevel,t.assembleWeldLevel,t.hotLevel,t.metalRotateLevel,t.weldLevel,t.engineeruid,p.bpminstanceid " +
                "FROM proc_component_techer t, proj_plantask p where t.plantaskid=p.plantaskid and t.plantaskid=?";
        List<Map<String, Object>> techerList = jdbcTemplate.queryForList(sql, componentId);
        String instanceId = (techerList!=null && techerList.size()>0 && techerList.get(0).get("bpminstanceid")!=null) ? techerList.get(0).get("bpminstanceid").toString() : null;
        if(instanceId==null || "0".equals(instanceId)){
            throw new BusinessException("该计划任务当前所处的流程节点无法进行路线卡评级分解维护！");
        }
        sql = "select p.processid,p.statusid,pt.cardtype,pt.direct from proc_process p, proc_process_z_type pt " +
                "where p.typeid=pt.typeid and pt.cardtype=1 and p.active=1 and p.plantaskid=?";
        List<Map<String, Object>> processList = jdbcTemplate.queryForList(sql, componentId);
        Map<String,Long> typeMap = new HashMap<>();
        for(Map<String, Object> pMap:processList) {
            typeMap.put(pMap.get("direct").toString(), (Long) pMap.get("statusid"));
        }
        if (StringUtil.isNotEmpty(techerList.get(0).get("metalLevel")) && !"D".equals(techerList.get(0).get("metalLevel").toString())) {
            Long statusId = typeMap.get("JG");
            map.put("JG", (statusId!=null && statusId==6) ? 0 : 1);
        }
        if (StringUtil.isNotEmpty(techerList.get(0).get("coldLevel")) && !"D".equals(techerList.get(0).get("coldLevel").toString())) {
            Long statusId = typeMap.get("LZ");
            map.put("LZ", (statusId!=null && statusId==6) ? 0 : 1);
        }
        if (StringUtil.isNotEmpty(techerList.get(0).get("assembleWeldLevel")) && !"D".equals(techerList.get(0).get("assembleWeldLevel").toString())) {
            Long statusId = typeMap.get("ZH");
            map.put("ZH", (statusId!=null && statusId==6) ? 0 : 1);
        }
        if (StringUtil.isNotEmpty(techerList.get(0).get("hotLevel")) && !"D".equals(techerList.get(0).get("hotLevel").toString())) {
            Long statusId = typeMap.get("RD");
            map.put("RD", (statusId!=null && statusId==6) ? 0 : 1);
        }
        if (StringUtil.isNotEmpty(techerList.get(0).get("metalRotateLevel")) && !"D".equals(techerList.get(0).get("metalRotateLevel").toString())) {
            Long statusId = typeMap.get("WJ");
            map.put("WJ", (statusId!=null && statusId==6) ? 0 : 1);
        }
        String uid = ContextUtil.getCurrentUserId();
        if (ContextUtil.currentUserIsAdmin()) {
            return map;
        } else {
            //只有对应计划任务的的工艺编制、工艺规划组的班组长、PLAN工艺管理员角色
            List<String> managerUids = EtechUserUtil.getManagerIdListByDepartId(169L);
            String engineerUid = techerList.get(0).get("engineeruid") != null ? techerList.get(0).get("engineeruid").toString() : null;
            if ((engineerUid != null && uid.equals(engineerUid))
                    || (managerUids != null && String.join(",", managerUids).contains(uid))
                    || commonService.hasRole("process_admin")) {
                //return map;
            } else {
                throw new BusinessException("对不起，该用户没有操作权限，无法进行该操作！");
            }
        }
        String[] nodes = new String[]{"T10.2","T10.3","T10.4","T10.5","T10.6","T10.7","T10.9"};
        if(!commonService.isInCurrentNodes(instanceId, componentId.toString(), nodes)){
            throw new BusinessException("该计划任务当前所处的流程节点无法进行路线卡评级分解维护！");
        }
        return map;
    }
    private String getLeveType(String direct){
        String levelType = "";
        if("JG".equals(direct)) {
            levelType = "metal";
        }else if("LZ".equals(direct)) {
            levelType = "cold";
        }else if("ZH".equals(direct)) {
            levelType = "assembleWeld";
        }else if("RD".equals(direct)) {
            levelType = "hot";
        }else if("WJ".equals(direct)) {
            levelType = "metalRotate";
        }else if("ZP".equals(direct)) {
            levelType = "assembleFit";
        }
        return levelType;
    }
    //管理员新增路线卡
    public void addRouteRevByAdmin(Long processId, Long partsId) throws Exception {
        JSONObject object = new JSONObject();
        String sql = "select t3.direct,t2.plantaskid,t2.plantasknum,t2.plantaskname,t4.component_SAPnum " +
                "from proc_process t1 join proj_plantask t2 on t1.plantaskid=t2.plantaskid join proc_process_z_type t3 on t1.typeid=t3.typeid " +
                "left join prod_component t4 on t1.plantaskid=t4.componentid where t1.processid=?";
        Map<String,Object> processMap = jdbcTemplate.queryForMap(sql, processId);
        if(partsId!=null && partsId>0) {
            sql = "select partsname,parts_SAPnum from prod_parts where partsid=?";
            Map<String,Object> partsMap = jdbcTemplate.queryForMap(sql, partsId);
            object.put("partsid", partsId);
            object.putAll(partsMap);
        }
        object.put("processid", processId);
        object.put("plantaskid", processMap.get("plantaskid"));
        object.put("plantaskname", processMap.get("plantaskname"));
        object.put("materialNo", processMap.get("component_SAPnum"));
        this.creatRouteRev(object, this.getLeveType(processMap.get("direct").toString()));
    }
    //初始化零件路线卡
    @Transactional(propagation= Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public Long creatRouteRev(JSONObject object, String levelType) {
        String version = StringUtil.isNotEmpty(object.getString("amendNum")) ? object.getString("amendNum") : "00";
        Long partsId = object.getLong("partsid");
        String preRouteName = StringUtil.isNotEmpty(object.getString("partsname"))? object.getString("partsname"): object.getString("plantaskname");
        SppRouteRev route = new SppRouteRev();
        route.setRouteRevId(IdUtil.getUId());
        route.setPartsid(partsId);
        route.setPlantaskid(object.getLong("plantaskid"));
        route.setProcessid(object.getLong("processid"));
        route.setActive(1);
        route.setStatusid(1);
        route.setIsTemplate(0);
        if ("metal".equals(levelType)) {
            route.setProcessTypeId(1L);
            route.setRouteName(preRouteName + "-金工");
            route.setMaterialNo(object.getString("parts_SAPnum"));
        } else if ("cold".equals(levelType)) {
            route.setProcessTypeId(3L);
            route.setRouteName(preRouteName + "-冷作");
            if(StringUtil.isNotEmpty(object.getString("parts_SAPnum")) && object.getString("parts_SAPnum").endsWith("0")) {
                route.setMaterialNo(object.getString("parts_SAPnum").substring(0, object.getString("parts_SAPnum").length()-1) + "N");
            }
        } else if ("assembleWeld".equals(levelType)) {
            route.setProcessTypeId(4L);
            route.setRouteName(preRouteName + "-装焊");
            if(StringUtil.isNotEmpty(object.getString("parts_SAPnum")) && object.getString("parts_SAPnum").endsWith("0")) {
                route.setMaterialNo(object.getString("parts_SAPnum").substring(0, object.getString("parts_SAPnum").length()-1) + "N");
            }
        } else if ("hot".equals(levelType)) {
            route.setProcessTypeId(5L);
            route.setRouteName(preRouteName + "-热锻");
            if(StringUtil.isNotEmpty(object.getString("parts_SAPnum")) && object.getString("parts_SAPnum").endsWith("0")) {
                route.setMaterialNo(object.getString("parts_SAPnum").substring(0, object.getString("parts_SAPnum").length()-1) + "D5");
            }
        } else if ("metalRotate".equals(levelType)) {
            route.setProcessTypeId(6L);
            route.setRouteName(preRouteName + "-五金");
            if(StringUtil.isNotEmpty(object.getString("parts_SAPnum")) && object.getString("parts_SAPnum").endsWith("0")) {
                route.setMaterialNo(object.getString("parts_SAPnum").substring(0, object.getString("parts_SAPnum").length()-1) + "W");
            }
        } else if ("assembleFit".equals(levelType)) {//装配特殊处理
            route.setProcessTypeId(2L);
            route.setRouteName(object.getString("plantaskname") + "-装配");
            route.setMaterialNo(object.getString("materialNo"));
        }
        //检查路线卡是否已存在
        String sql = "select route_rev_id from spp_route_rev where active=1 and processid=? and partsid=? and version=? and process_type_id=?";
        List<Map<String,Object>> list = jdbcTemplate.queryForList(sql, route.getProcessid(), route.getPartsid(), version, route.getProcessTypeId());
        if(list!=null && list.size()>0) {
            return null;
        }
        if(StringUtil.isNotEmpty(object.getString("amendNum"))) {//修改单新增
            route.setVersion(object.getString("amendNum"));
            route.setCurrVer(0);
        }else {
            route.setVersion("00");
            route.setCurrVer(1);
        }
        route.setSerialNum(this.getNextRouteCardSerial());
        super.save(route);
        return route.getRouteRevId();
    }

    //删除路线卡
    private void deleteRouteRev(Long planTaskId, Long partsId, String levelType) {
        Long processTypeId = null;
        if ("metal".equals(levelType)) {
            processTypeId = 1L;
        } else if ("cold".equals(levelType)) {
            processTypeId = 3L;
        } else if ("assembleWeld".equals(levelType)) {
            processTypeId = 4L;
        } else if ("hot".equals(levelType)) {
            processTypeId = 5L;
        } else if ("metalRotate".equals(levelType)) {
            processTypeId = 6L;
        }
        super.remove(Wrappers.<SppRouteRev>lambdaUpdate()
                .eq(SppRouteRev::getPlantaskid, planTaskId)
                .eq(SppRouteRev::getPartsid, partsId)
                .eq(SppRouteRev::getProcessTypeId, processTypeId));
    }

    //初始化路线卡评级分解
    public void creatPartsTechAndRouteRev(Long planTaskId) {
        String sql = "select plantaskid,metalLevel,assembleFitLevel,coldLevel,assembleWeldLevel,hotLevel,metalRotateLevel from proc_component_techer where plantaskid=?";
        List<Map<String, Object>> techList = jdbcTemplate.queryForList(sql, planTaskId);
        JSONObject object = new JSONObject(techList.get(0));
        sql = "select routexid,code,name from prod_parts_z_routex where active=1";
        List<Map<String, Object>> routexList = jdbcTemplate.queryForList(sql);
        Map<String, String> routexMap = new HashMap<>();
        for (Map<String, Object> map : routexList) {
            routexMap.put(map.get("routexid").toString(), map.get("name").toString());
        }
        sql = "select p.partsid,p.partsnum,p.partsname,p.billet_SAPnum,pa.name attributename,p.parts_SAPnum," +
                "p.route1,p.route2,p.route3,p.route4,p.route5,p.route6,p.route7,p.route8,p.route9,p.route10,p.route11,p.route12,p.route13  " +
                "from prod_parts p left join prod_parts_z_attribute pa on p.partsAttributeid=pa.partsAttributeid where p.active=1 and p.original_componentid=?";
        List<Map<String, Object>> partsList = jdbcTemplate.queryForList(sql, planTaskId);
        if (partsList != null && partsList.size() > 0) {
            Map<String, String> routeNameMap = new HashMap<>();
            for (Map<String, Object> map : partsList) {
                String routeName = "";
                for (int i = 1; i < 14; i++) {
                    if (StringUtil.isNotEmpty(map.get("route" + i)) && routexMap.containsKey(map.get("route" + i).toString())) {
                        routeName = routeName + "," + routexMap.get(map.get("route" + i).toString());
                    }
                }
                routeNameMap.put(map.get("partsid").toString(), routeName);
            }
            Map<String, Long> partsTechMap = new HashMap<>();
            //五金路线卡：零件毛坯物料号以“W”结尾；或者零件属性为“M5”或“M6”；或者路线1为“毛”的零件且后续走向中没有”叶片“
            if (StringUtil.isNotEmpty(object.getString("metalRotateLevel"))) {
                for (Map<String, Object> map : partsList) {
                    String billetSAPnum = map.get("billet_SAPnum") != null ? map.get("billet_SAPnum").toString() : null;
                    String attributeName = map.get("attributename") != null ? map.get("attributename").toString() : null;
                    String route1 = map.get("route1") != null ? map.get("route1").toString() : null;
                    Long partsId = (Long) map.get("partsid");
                    if ((StringUtil.isNotEmpty(billetSAPnum) && billetSAPnum.endsWith("W"))
                            || (StringUtil.isNotEmpty(attributeName) && "M5,M6".contains(attributeName))
                            || (StringUtil.isNotEmpty(route1) && "毛".equals(routexMap.get(route1)) && !routeNameMap.get(map.get("partsid").toString()).contains("叶片"))) {

                        Long partsTechId = this.saveOrUpdatePartsTech(null, partsId, planTaskId,
                                null, null, null, null, 1);
                        partsTechMap.put(partsId.toString(), partsTechId);
                    }
                }
            }
            //热锻路线卡：零件毛坯物料号以“D5”结尾；或者零件属性为“D5”或“D6”
            if (StringUtil.isNotEmpty(object.getString("hotLevel"))) {
                for (Map<String, Object> map : partsList) {
                    String billetSAPnum = map.get("billet_SAPnum") != null ? map.get("billet_SAPnum").toString() : null;
                    String attributeName = map.get("attributename") != null ? map.get("attributename").toString() : null;
                    Long partsId = (Long) map.get("partsid");
                    if ((StringUtil.isNotEmpty(billetSAPnum) && billetSAPnum.endsWith("D5"))
                            || (StringUtil.isNotEmpty(attributeName) && "D5,D6".contains(attributeName))) {

                        Long partsTechId = this.saveOrUpdatePartsTech(partsTechMap.get(partsId.toString()), (Long) map.get("partsid"), planTaskId,
                                null, null, 1, null, null);
                        partsTechMap.put(partsId.toString(), partsTechId);
                    }
                }
            }
            //冷作路线卡：零件毛坯物料号以“N”结尾且零件图号不以“G01”结尾
            if (StringUtil.isNotEmpty(object.getString("coldLevel"))) {
                for (Map<String, Object> map : partsList) {
                    String billetSAPnum = map.get("billet_SAPnum") != null ? map.get("billet_SAPnum").toString() : null;
                    String partsNum = map.get("partsnum").toString();
                    Long partsId = (Long) map.get("partsid");
                    if (StringUtil.isNotEmpty(partsNum) && !partsNum.endsWith("G01")
                            && StringUtil.isNotEmpty(billetSAPnum) && billetSAPnum.endsWith("N")) {

                        Long partsTechId = this.saveOrUpdatePartsTech(partsTechMap.get(partsId.toString()), partsId, planTaskId,
                                null, 1, null, null, null);
                        partsTechMap.put(partsId.toString(), partsTechId);
                    }
                }
            }
            //装焊路线卡：零件毛坯物料号以“N”结尾且零件图号以“G01”结尾
            if (StringUtil.isNotEmpty(object.getString("assembleWeldLevel"))) {
                for (Map<String, Object> map : partsList) {
                    String partsNum = map.get("partsnum").toString();
                    String billetSAPnum = map.get("billet_SAPnum") != null ? map.get("billet_SAPnum").toString() : null;
                    Long partsId = (Long) map.get("partsid");
                    if (StringUtil.isNotEmpty(partsNum) && partsNum.endsWith("G01")
                            && StringUtil.isNotEmpty(billetSAPnum) && billetSAPnum.endsWith("N")) {

                        Long partsTechId = this.saveOrUpdatePartsTech(partsTechMap.get(partsId.toString()), partsId, planTaskId,
                                null, null, null, 1, null);
                        partsTechMap.put(partsId.toString(), partsTechId);
                    }
                }
            }
            //金工路线卡：路线1~路线13中含有其中任何一个字段的：汽机、(汽机)、燃机、(燃机)、配套、(配套)、冷金、装焊、(装焊)
            if (StringUtil.isNotEmpty(object.getString("metalLevel"))) {
                for (Map<String, Object> map : partsList) {
                    String routeName = routeNameMap.get(map.get("partsid").toString());
                    Long partsId = (Long) map.get("partsid");
                    if (routeName.contains("汽机") || routeName.contains("(汽机)") || routeName.contains("燃机") || routeName.contains("(燃机)")
                            || routeName.contains("配套") || routeName.contains("(配套)") || routeName.contains("冷金")
                            || routeName.contains("装焊") || routeName.contains("(装焊)")) {

                        Long partsTechId = this.saveOrUpdatePartsTech(partsTechMap.get(partsId.toString()), partsId, planTaskId,
                                1, null, null, null, null);
                        partsTechMap.put(partsId.toString(), partsTechId);
                    }
                }
            }
        }
    }

    //保存或者更新路线卡表
    private Long saveOrUpdatePartsTech(Long partsTechId, Long partsId, Long planTaskId, Integer hasMetal, Integer hasCold,
                                       Integer hasHot, Integer hasAssembleWeld, Integer hasMetalRotate) {
        if (partsTechId != null && partsTechId > 0) {
            PartsTech partsTech = new PartsTech();
            partsTech.setPartsTechId(partsTechId);
            partsTech.setHasMetal(hasMetal);
            partsTech.setHasCold(hasCold);
            partsTech.setHasHot(hasHot);
            partsTech.setHasAssembleWeld(hasAssembleWeld);
            partsTech.setHasMetalRotate(hasMetalRotate);
            partsTechMapper.updateById(partsTech);
        } else {
            PartsTech partsTech = new PartsTech();
            partsTech.setPartsTechId(IdUtil.getUId());
            partsTech.setPartsid(partsId);
            partsTech.setComponentid(planTaskId);
            partsTech.setHasMetal(hasMetal);
            partsTech.setHasCold(hasCold);
            partsTech.setHasHot(hasHot);
            partsTech.setHasAssembleWeld(hasAssembleWeld);
            partsTech.setHasMetalRotate(hasMetalRotate);
            partsTechMapper.insert(partsTech);
            partsTechId = partsTech.getPartsTechId();
        }
        return partsTechId;
    }

    /**
     * 获取关联工装
     *
     * @param routeRevId
     * @param stepId
     * @return
     */
    public List getRefTools(Long routeRevId, Long stepId) {
        return sppRelToolService.getRefTools(routeRevId, REL_TARGET_TYPE, stepId);
    }

    /**
     * 更新关联工装
     *
     * @param paramMap
     */
    public void updateRefTool(Map<String, Object> paramMap) {
        Long routeRevId = MapUtil.getLong(paramMap, "targetId");
        Long stepId = MapUtil.getLong(paramMap, "stepId");
        JSONArray jsonArray = cn.hutool.json.JSONUtil.parseArray(MapUtil.getStr(paramMap, "toolingList"));
        sppRelToolService.updateRefTool(routeRevId, REL_TARGET_TYPE, stepId, jsonArray);
    }

    /**
     * 添加标准工艺描述失败
     *
     * @param paramMap
     */
    public void addStandardProcDesc(Map<String, Object> paramMap) {
        Long stepId = MapUtil.getLong(paramMap, "stepId");
        String descContent = MapUtil.getStr(paramMap, "descContent");
        String amendNum = MapUtil.getStr(paramMap, "amendnum");

        SppRouteStep sppRouteStep = sppRouteStepService.getById(stepId);
        if (sppRouteStep != null) {
            sppRouteStep.setStepContent(descContent);
            String dbAmends = sppRouteStep.getAmends();
            if(StringUtil.isEmpty(dbAmends)) {
                sppRouteStep.setAmends(amendNum);
            }else if(StringUtil.isNotEmpty(amendNum) && !dbAmends.contains(amendNum)) {
                sppRouteStep.setAmends(dbAmends + "；" + amendNum);
            }
            sppRouteStepService.updateById(sppRouteStep);
        }
    }

    //检查路线卡修改
    public String checkRouteAmend(Long processId, Long amendId, Long targetId){

        String sql = "select a.amendid,a.business_id,a.compileuserid,a.checkuserid,a.reviewuserid,p.designdprtid,ab.bpminstanceid " +
                "from proj_amend a, proj_amend_bpe ab, proc_process p " +
                "where a.business_id=p.processid and a.amendid=ab.amendid and ab.active=1 and a.scope='process'and a.business_id=? and a.amendid=?";
        List<Map<String, Object>> amendList = jdbcTemplate.queryForList(sql, processId, amendId);
        if (amendList == null || amendList.size() == 0 || amendList.get(0).get("bpminstanceid") == null
                || (Long) amendList.get(0).get("bpminstanceid") == 0) {
            return "对不起，输入的修改单号没有关联此工艺，请检查！";
        }
        if(targetId!=null && targetId>0) {
            int num = partsTechAmendMapper.selectCount(Wrappers.<PartsTechAmend>lambdaQuery()
                    .eq(PartsTechAmend::getTargetId, targetId).eq(PartsTechAmend::getAmendid, amendId));
            if(num==0){
                return "对不起，输入的修改单号没有关联此工艺，请检查！";
            }
        }
        if (!ContextUtil.currentUserIsAdmin()) {
            String uid = ContextUtil.getCurrentUserId();
            String compileuserId = amendList.get(0).get("compileuserid")!=null ? amendList.get(0).get("compileuserid").toString() : null;
            String designdprtId = amendList.get(0).get("designdprtid")!=null ? amendList.get(0).get("designdprtid").toString() : null;
            String checkuserId = amendList.get(0).get("checkuserid")!=null ? amendList.get(0).get("checkuserid").toString() : null;
            String reviewuserId = amendList.get(0).get("reviewuserid")!=null ? amendList.get(0).get("reviewuserid").toString() : null;

            //对应修改单的编制、校对、审核、工艺卡编制科室的班组长、PLAN工艺管理员角色
            List<String> uidList = null;
            if(designdprtId!=null && !"0".equals(designdprtId)){
                uidList = EtechUserUtil.getManagerIdListByDepartId(Long.parseLong(designdprtId));
            }
            if((compileuserId!= null && uid.equals(compileuserId))
                    || (checkuserId!= null && uid.equals(checkuserId))
                    || (reviewuserId!= null && uid.equals(reviewuserId))
                    || (uidList != null && String.join(",", uidList).contains(uid))
                    || commonService.hasRole("process_admin")) {
            }else {
                return "对不起，您没有此修改单的修改权限！";
            }
        }
        sql = "select bpeid,amendid from proj_amend_bpe where active=1 and isModified=1 and amendid=?";
        List<Map<String, Object>> bpeList = jdbcTemplate.queryForList(sql, amendId);
        if (bpeList != null && bpeList.size() > 0) {
            return "对不起，该工艺卡修改单已入库，无法进行修改操作！";
        }
        return "success";
    }
    //校验权限 返回参数
    public Map checkRouteAmendPower(Long amendId) {
        String sql = "select a.compileuserid,p.designdprtid,p.processid,pt.direct,pt.cardtype,p.plantaskid " +
                "from proj_amend a, proc_process p, proc_process_z_type pt " +
                "where a.business_id=p.processid and p.typeid=pt.typeid and a.scope='process' and a.amendid=?";
        List<Map<String,Object>> amendList = jdbcTemplate.queryForList(sql, amendId);
        if(amendList==null || amendList.size()==0){
            throw new BusinessException("对不起，输入的修改单号没有关联此工艺，请检查！");
        }
        if (!ContextUtil.currentUserIsAdmin()) {
            String uid = ContextUtil.getCurrentUserId();
            String compileuserId = amendList.get(0).get("compileuserid")!=null ? amendList.get(0).get("compileuserid").toString() : null;
            String designdprtId = amendList.get(0).get("designdprtid")!=null ? amendList.get(0).get("designdprtid").toString() : null;

            //对应修改单的编制、工艺卡编制科室的班组长、PLAN工艺管理员角色
            List<String> uidList = null;
            if(designdprtId!=null && !"0".equals(designdprtId)){
                uidList = EtechUserUtil.getManagerIdListByDepartId(Long.parseLong(designdprtId));
            }
            if((compileuserId!= null && uid.equals(compileuserId))
                    || (uidList != null && String.join(",", uidList).contains(uid))
                    || commonService.hasRole("process_admin")) {
            }else {
                throw new BusinessException("对不起，您没有此修改单的修改权限！");
            }
        }
        sql = "select bpeid,amendid from proj_amend_bpe where active=1 and isModified=1 and amendid=?";
        List<Map<String, Object>> bpeList = jdbcTemplate.queryForList(sql, amendId);
        if (bpeList != null && bpeList.size() > 0) {
            throw new BusinessException("对不起，该工艺卡修改单已入库，无法进行修改操作！");
        }
        Long processId = (Long) amendList.get(0).get("processid");
        Integer cardType = (Integer) amendList.get(0).get("cardtype");
        String direct = amendList.get(0).get("direct").toString();
        String planTaskId = amendList.get(0).get("plantaskid").toString();
        Map resMap = new HashMap();
        resMap.put("cardType", cardType);
        resMap.put("plantaskid", planTaskId);
        resMap.put("processid", processId);
        //查询装配工艺卡表ID
        if(cardType==1) {//路线卡
            sql = "select process_type_id from spp_route_z_process_type where `code`=?";
            List<Map<String, Object>> typeList = jdbcTemplate.queryForList(sql, direct);
            resMap.put("process_type_id", typeList.get(0).get("process_type_id"));
        }else if(cardType==2) {//工序卡
            sql = "select op_type_id from spp_operation_z_type where `code`=?";
            List<Map<String, Object>> typeList = jdbcTemplate.queryForList(sql, direct);
            resMap.put("op_type_id", typeList.get(0).get("op_type_id"));
        }
        return resMap;
    }

    public Long createPartsTechAmend(Long partsId, Integer targetType, Long targetId, Long newTargetId,
                                     Long targetTypeId, Integer changeMode, Long amendId){
        PartsTechAmend partsTechAmend = new PartsTechAmend();
        partsTechAmend.setPartsAmendId(IdUtil.getUId());
        partsTechAmend.setPartsid(partsId);
        partsTechAmend.setTargetType(targetType);
        partsTechAmend.setTargetId(targetId);
        partsTechAmend.setNewTargetId(newTargetId);
        partsTechAmend.setTargetTypeId(targetTypeId);
        partsTechAmend.setChangeMode(changeMode);
        partsTechAmend.setAmendid(amendId);
        partsTechAmendMapper.insert(partsTechAmend);
        return partsTechAmend.getPartsAmendId();
    }
    //工艺卡修改任务分解行编辑
    public void saveOrUpdateAmendForLine(JSONObject object) throws Exception{
        Long amendId = object.getLong("amendid");
        String listType = object.getString("listType");
        boolean a37Flag = true;//流程是否处于任务分解节点
        List<JSONObject> objectList = (List<JSONObject>) object.get("dataList");
        String sql = "select count(1) num from bpm_task where node_id_='A37' and inst_id_=(" +
                "select bpminstanceid from proj_amend_bpe where active=1 and amendid=?) ";
        List<Map<String, Object>> taskList = jdbcTemplate.queryForList(sql, amendId);
        if (taskList == null || taskList.size() == 0 || Integer.parseInt(taskList.get(0).get("num").toString()) == 0) {
            a37Flag = false;
        }
        sql = "select a.amendnum,p.processid,pt.direct,rpt.process_type_id from proj_amend a, proc_process p, proc_process_z_type pt, spp_route_z_process_type rpt " +
                "where a.business_id=p.processid and p.typeid=pt.typeid and pt.direct=rpt.`code` and a.amendid=?";
        List<Map<String, Object>> amendList = jdbcTemplate.queryForList(sql, amendId);
        for (JSONObject obj : objectList) {
            /*PartsTechAmend partsTechAmend = JSONObject.toJavaObject(obj, PartsTechAmend.class);
            boolean newFlag = false;
            //修改表新增、更新
            if (partsTechAmend.getPartsAmendId() == null || partsTechAmend.getPartsAmendId() == 0) {
                partsTechAmend.setPartsAmendId(IdUtil.getUId());
                partsTechAmend.setAmendid(amendId);
                partsTechAmend.setTargetType(1);
                partsTechAmend.setTargetTypeId((Long) amendList.get(0).get("process_type_id"));
                partsTechAmend.setTargetId(obj.getLong("route_rev_id"));
                partsTechAmendMapper.insert(partsTechAmend);
                newFlag = true;
            }else {
                partsTechAmendMapper.updateById(partsTechAmend);
                if(partsTechAmend.getNewTargetId()!=null && partsTechAmend.getNewTargetId()>0 && partsTechAmend.getChangeMode()!=null) {
                    SppRouteRev sppRouteRev = new SppRouteRev();
                    sppRouteRev.setRouteRevId(partsTechAmend.getNewTargetId());
                    sppRouteRev.setStatusid(partsTechAmend.getChangeMode()==0 ? 2 : 1);
                    super.updateById(sppRouteRev);
                }
            }
            Long newRouteRevId = null;
            if("add".equals(listType)){//新增清单
                if(partsTechAmend.getChangeMode()==0 && !newFlag) {//新增清单删除
                    partsTechAmendMapper.deleteById(partsTechAmend.getPartsAmendId());
                    if (!a37Flag) {//物理删除新版本路线表
                        this.deleteAmendRouteRevs(partsTechAmend.getNewTargetId(), (Long) amendList.get(0).get("processid"),
                                partsTechAmend.getPartsid(), amendList.get(0).get("amendnum").toString());
                    }
                }else if(partsTechAmend.getChangeMode()==1 && !a37Flag){//新增清单新增
                    newRouteRevId = this.creatRouteAmendVersion(partsTechAmend.getPartsid(), amendList.get(0).get("direct").toString(),
                            (Long) amendList.get(0).get("processid"), amendList.get(0).get("amendnum").toString());
                }
            }else {//变更清单
                if (obj.getInteger("change_mode") == null) {
                    partsTechAmendMapper.deleteById(partsTechAmend.getPartsAmendId());
                    if(!a37Flag) {
                        this.deleteAmendRouteRevs(partsTechAmend.getNewTargetId(), (Long) amendList.get(0).get("processid"),
                                partsTechAmend.getPartsid(), amendList.get(0).get("amendnum").toString());
                    }
                } else if(!a37Flag) {
                    //生成新版本关联路线表
                    newRouteRevId = this.upgradeRouteVersion((Long) amendList.get(0).get("processid"), partsTechAmend.getTargetId(),partsTechAmend.getPartsid(),
                            amendList.get(0).get("amendnum").toString(), obj.getInteger("change_mode")==0 ? 2 : 1);
                }
            }
            if(newRouteRevId!=null && newRouteRevId>0){
                partsTechAmend.setNewTargetId(newRouteRevId);
                partsTechAmendMapper.updateById(partsTechAmend);
            }*/
            Long newRouteRevId = null;
            try {
                newRouteRevId = this.saveOrUpdateAmendForLineSub(obj, amendList, amendId, listType, a37Flag);
            }catch (Exception e){
                e.printStackTrace();
                //单独回滚路线卡表
                if(newRouteRevId!=null && "add".equals(listType) && obj.getInteger("change_mode")==1 && !a37Flag) {
                    super.removeById(newRouteRevId);
                }
                throw new Exception(e);
            }
        }
    }
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrUpdateAmendForLineSub(JSONObject obj, List<Map<String, Object>> amendList, Long amendId, String listType, boolean a37Flag) throws Exception{
        PartsTechAmend partsTechAmend = JSONObject.toJavaObject(obj, PartsTechAmend.class);
        boolean newFlag = false;
        //修改表新增、更新
        if (partsTechAmend.getPartsAmendId() == null || partsTechAmend.getPartsAmendId() == 0) {
            partsTechAmend.setPartsAmendId(IdUtil.getUId());
            partsTechAmend.setAmendid(amendId);
            partsTechAmend.setTargetType(1);
            partsTechAmend.setTargetTypeId((Long) amendList.get(0).get("process_type_id"));
            partsTechAmend.setTargetId(obj.getLong("route_rev_id"));
            partsTechAmendMapper.insert(partsTechAmend);
            newFlag = true;
        }else {
            partsTechAmendMapper.updateById(partsTechAmend);
            if(partsTechAmend.getNewTargetId()!=null && partsTechAmend.getNewTargetId()>0 && partsTechAmend.getChangeMode()!=null) {
                SppRouteRev sppRouteRev = new SppRouteRev();
                sppRouteRev.setRouteRevId(partsTechAmend.getNewTargetId());
                sppRouteRev.setStatusid(partsTechAmend.getChangeMode()==0 ? 2 : 1);
                super.updateById(sppRouteRev);
            }
        }
        Long newRouteRevId = null;
        if("add".equals(listType)){//新增清单
            if(partsTechAmend.getChangeMode()==0 && !newFlag) {//新增清单删除
                partsTechAmendMapper.deleteById(partsTechAmend.getPartsAmendId());
                if (!a37Flag) {//物理删除新版本路线表
                    this.deleteAmendRouteRevs(partsTechAmend.getNewTargetId(), (Long) amendList.get(0).get("processid"),
                            partsTechAmend.getPartsid(), amendList.get(0).get("amendnum").toString());
                }
            }else if(partsTechAmend.getChangeMode()==1 && !a37Flag){//新增清单新增
                newRouteRevId = this.creatRouteAmendVersion(partsTechAmend.getPartsid(), amendList.get(0).get("direct").toString(),
                        (Long) amendList.get(0).get("processid"), amendList.get(0).get("amendnum").toString());
            }
        }else {//变更清单
            if (obj.getInteger("change_mode") == null) {
                partsTechAmendMapper.deleteById(partsTechAmend.getPartsAmendId());
                if(!a37Flag) {
                    this.deleteAmendRouteRevs(partsTechAmend.getNewTargetId(), (Long) amendList.get(0).get("processid"),
                            partsTechAmend.getPartsid(), amendList.get(0).get("amendnum").toString());
                }
            } else if(!a37Flag) {
                //生成新版本关联路线表
                newRouteRevId = this.upgradeRouteVersion((Long) amendList.get(0).get("processid"), partsTechAmend.getTargetId(),partsTechAmend.getPartsid(),
                        amendList.get(0).get("amendnum").toString(), obj.getInteger("change_mode")==0 ? 2 : 1);
            }
        }
        if(newRouteRevId!=null && newRouteRevId>0){
            partsTechAmend.setNewTargetId(newRouteRevId);
            partsTechAmendMapper.updateById(partsTechAmend);
        }
        return newRouteRevId;
    }
    //删除修改单新增的路线卡
    private void deleteAmendRouteRevs(Long routeRevId, Long processId, Long partsId, String amendNum) {
        if(routeRevId==null || routeRevId==0){
            SppRouteRev sppRouteRev = super.getOne(Wrappers.<SppRouteRev>lambdaQuery()
                    .eq(SppRouteRev::getProcessid, processId)
                    .eq(SppRouteRev::getPartsid, partsId)
                    .eq(SppRouteRev::getVersion, amendNum));
            routeRevId = sppRouteRev.getRouteRevId();
        }
        sppRelSamService.remove(Wrappers.<SppRelSam>lambdaUpdate().eq(SppRelSam::getTargetType, 1).eq(SppRelSam::getTargetId, routeRevId));
        sppRelToolService.remove(Wrappers.<SppRelTool>lambdaUpdate().eq(SppRelTool::getTargetType, 1).eq(SppRelTool::getTargetId, routeRevId));
        sppRelFileService.remove(Wrappers.<SppRelFile>lambdaUpdate().eq(SppRelFile::getTargetType, 1).eq(SppRelFile::getTargetId, routeRevId));
        sppRouteStepService.remove(Wrappers.<SppRouteStep>lambdaUpdate().eq(SppRouteStep::getRouteRevId, routeRevId));
        sppRouteOpService.remove(Wrappers.<SppRouteOp>lambdaUpdate().eq(SppRouteOp::getRouteRevId, routeRevId));
        super.removeById(routeRevId);
    }
    //生成路线卡的修改单版本
    public void createAmendRouteRevs(Long processId, Long amendId, String amendNum) {
        String sql = "select ta.*,pt.`code` processType from proc_parts_tech_amend ta, spp_route_z_process_type pt " +
                "where ta.target_type_id=pt.process_type_id and ta.target_type=1 and ta.amendid=?";
        List<Map<String, Object>> techAmendList = jdbcTemplate.queryForList(sql, amendId);
        if(techAmendList!=null && techAmendList.size()>0){
            for(Map<String, Object> map: techAmendList){
                Integer changeMode = (Integer) map.get("change_mode");
                Long newRouteRevId = null;
                if(changeMode==0 || changeMode==2){//删除、修改
                    newRouteRevId = this.upgradeRouteVersion(null, (Long) map.get("target_id"), null, amendNum, changeMode==0 ? 2 : 1);
                }else {//新增
                    newRouteRevId = this.creatRouteAmendVersion((Long) map.get("partsid"), map.get("processType").toString(), processId, amendNum);
                }
                if(newRouteRevId!=null && newRouteRevId>0){
                    PartsTechAmend partsTechAmend = new PartsTechAmend() ;
                    partsTechAmend.setPartsAmendId((Long) map.get("parts_amend_id"));
                    partsTechAmend.setNewTargetId(newRouteRevId);
                    partsTechAmendMapper.updateById(partsTechAmend);
                }
            }
        }
    }

    //路线卡修改：新增生成新版本
    private Long creatRouteAmendVersion(Long partsId, String processType, Long processId, String amendNum) {
        String sql = "select p.partsid,p.partsnum,p.partsname,p.parts_SAPnum,p.original_componentid plantaskid from prod_parts p where p.partsid=?";
        List<Map<String, Object>> partsList = jdbcTemplate.queryForList(sql, partsId);
        JSONObject object = new JSONObject(partsList.get(0));
        object.put("processid", processId);
        object.put("amendNum", amendNum);
        return this.creatRouteRev(object, this.getLeveType(processType));
    }
    //路线卡修改：变更、删除生成新版本
    private Long upgradeRouteVersion(Long processId, Long routeRevId, Long partsId, String amendNum, Integer statusId) {
        if(processId!=null && processId>0) {
            SppRouteRev rev = super.getOne(Wrappers.<SppRouteRev>lambdaQuery()
                    .eq(SppRouteRev::getProcessid, processId)
                    .eq(SppRouteRev::getPartsid, partsId)
                    .eq(SppRouteRev::getVersion, amendNum));
            if (rev!=null) {
                return rev.getRouteRevId();
            }
        }
        SppRouteRev currRouteRev = super.getById(routeRevId);
        SppRouteRev newRouteRev = new SppRouteRev();
        BeanUtil.copyProperties(currRouteRev, newRouteRev);
        Long uid = Long.parseLong(ContextUtil.getCurrentUserId());
        newRouteRev.setRouteRevId(IdUtil.getUId());
        newRouteRev.setSerialNum(currRouteRev.getSerialNum());
        newRouteRev.setCurrVer(0);
        newRouteRev.setVersion(amendNum);
        newRouteRev.setActive(1);
        newRouteRev.setStatusid(statusId);
        newRouteRev.setPostuid(uid);
        newRouteRev.setPostdate(new Date());
        newRouteRev.setLastuid(uid);
        newRouteRev.setLastdate(new Date());
        super.save(newRouteRev);
        sppRouteOpService.copyFromRouteCard(routeRevId, newRouteRev.getRouteRevId(), amendNum, true, true);
        return newRouteRev.getRouteRevId();
    }
    //路线卡、工序卡节点批量提交
    public List<JSONObject> batchSubmitBpm(List<JSONObject> objectList){
        List<JSONObject> resultList = new ArrayList<>();
        List<JSONObject> params = new ArrayList<>();//流程提交参数
        Map<String, String> processMap = new HashMap<>();
        for(JSONObject object:objectList) {
            JSONObject paramObj = new JSONObject();
            JSONObject extendConf = new JSONObject();
            extendConf.put("nodeId", object.get("node_id_"));
            paramObj.put("extendConf", extendConf);
            paramObj.put("taskId", object.get("task_id_"));
            paramObj.put("instanceId", object.get("bpminstanceid"));
            paramObj.put("bizId", object.get("processid"));
            paramObj.put("action", "agree");
            String sql = "select key_ from bpm_definition where id_=(select def_id_ from bpm_instance where id_=?)";
            Map<String,Object> defMap = jdbcTemplate.queryForMap(sql, object.getString("bpminstanceid"));
            String defKey = defMap.get("key_").toString();
            String formKey = "normalProcProcess";//常规路线卡编制、常规工序卡编制
            if("specialProcessCard".equals(defKey)){//特殊工艺卡编制
                if("D1".equals(object.getString("node_id_"))){
                    formKey = "procProcessSpecial";
                }else {
                    formKey = "procProcess";
                }
            }
            paramObj.put("formKey", formKey);
            paramObj.put("defKey", defKey);
            params.add(paramObj);
            processMap.put(object.getString("processid"), object.getString("num"));
        }
        com.alibaba.fastjson.JSONArray jsonArray = etechBpmService.doActions(params);
        for(int i=0; i<jsonArray.size(); i++){
            JSONObject obj = jsonArray.getJSONObject(i);
            if("1".equals(obj.getString("flag"))){
                obj.put("resultStr", "success");
                obj.put("tips", "处理成功");
            }else{
                obj.put("resultStr", "fail");
                obj.put("tips", obj.get("msg"));
            }
            obj.put("num", processMap.get(obj.getString("bizId")));
            obj.remove("flag");
            obj.remove("msg");
            obj.remove("bizId");
            resultList.add(obj);
        }
        return resultList;
    }
    //生成路线卡分解信息
    public void createPartsTech() {
        String sql = "select distinct plantaskid from proc_process where (statusid is null or statusid in (0, 1)) and processid>0";
        List<Map<String, Object>> processList = jdbcTemplate.queryForList(sql);
        for(Map<String, Object> map:processList) {
            Long planTaskId = (Long) map.get("plantaskid");
            //流程结束的不处理
            sql = "select node_id_ from bpm_task where inst_id_>0 and inst_id_=(select bpminstanceid from proj_plantask where plantaskid=?)";
            List<Map<String, Object>> bpmTaskList = jdbcTemplate.queryForList(sql, planTaskId);
            if(bpmTaskList==null || bpmTaskList.size()==0 || "T18".equals(bpmTaskList.get(0).get("node_id_"))) {
                continue;
            }
            sql = "select p.partsid,p.partsnum,p.partsname,pt.`code` from prod_parts p, spp_route_rev rr, spp_route_z_process_type pt " +
                    "where p.original_componentid=rr.plantaskid and p.partsid=rr.partsid and p.original_componentid=rr.plantaskid " +
                    "and rr.process_type_id=pt.process_type_id and p.active=1 and p.original_componentid=?";
            List<Map<String, Object>> partsList = jdbcTemplate.queryForList(sql, planTaskId);
            for(Map<String, Object> partsMap:partsList) {
                PartsTech partsTech = partsTechMapper.selectOne(Wrappers.<PartsTech>lambdaQuery()
                        .eq(PartsTech::getPartsid, partsMap.get("partsid").toString())
                        .eq(PartsTech::getComponentid, planTaskId));
                Long partsTechId = null;
                if(partsTech!=null) {
                    partsTechId = partsTech.getPartsTechId();
                }
                String typeCode = partsMap.get("code").toString();
                if("JG".equals(typeCode)) {
                    this.saveOrUpdatePartsTech(partsTechId, (Long) partsMap.get("partsid"), planTaskId,
                            1, null, null, null, null);
                }else if("LZ".equals(typeCode)) {
                    this.saveOrUpdatePartsTech(partsTechId, (Long) partsMap.get("partsid"), planTaskId,
                            null, 1, null, null, null);
                }else if("ZH".equals(typeCode)) {
                    this.saveOrUpdatePartsTech(partsTechId, (Long) partsMap.get("partsid"), planTaskId,
                            null, null, null, 1, null);
                }else if("RD".equals(typeCode)) {
                    this.saveOrUpdatePartsTech(partsTechId, (Long) partsMap.get("partsid"), planTaskId,
                            null, null, 1, null, null);
                }else if("WJ".equals(typeCode)) {
                    this.saveOrUpdatePartsTech(partsTechId, (Long) partsMap.get("partsid"), planTaskId,
                            null, null, null, null, 1);
                }
                System.out.println("createPartsTech：" + partsMap.get("partsnum").toString());
            }
        }
    }
}
